<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="coinfaces">

        <title>命名管道的正确read方式</title>

    <link rel="stylesheet" href="../../theme/css/style.css">
    <link rel="stylesheet" href="../../theme/css/pygments.css">



</head>

<body>
    <div class="content">
<h1>命名管道的正确read方式</h1>    <p>
        under
            <a href="../../tags/bash/">bash</a>
            <a href="../../tags/fifo/">fifo</a>
    </p>
    <p>
        in <a href="../../categories/tech/">tech</a>
    </p>
    <p>Published: 2016-08-22</p>


    <p>最近写一个脚本，监控程序在后台写入命名管道，bash在前台用<tt class="docutils literal">read</tt>命令按行读取监控结果，并写到标准输出。我一开始是这么写的：</p>
<div class="highlight"><pre><span></span><span class="k">while</span> <span class="nb">read</span> line &lt;fifo<span class="p">;</span> <span class="k">do</span>
    <span class="nb">echo</span> <span class="s2">&quot;</span><span class="nv">$line</span><span class="s2">&quot;</span>
<span class="k">done</span>
</pre></div>
<p>这种方法由于频繁地在读取端打开关闭命名管道，会引起一些问题，比如丢数据，在一个终端输入以上命令，然后在另一个终端输入：</p>
<pre class="literal-block">
cat /etc/passwd &gt;fifo
</pre>
<p>能从命名管道中读出多少数据取决于系统繁忙程度以及读写的打开顺序，如果在读取端的循环里加入一条<tt class="docutils literal">sleep 0.1</tt>，则几乎可以肯定只能读出第一行数据。</p>
<p>另一个问题是如果写入端尝试写入数据的时候读取端关闭了管道，则写入端会收到<tt class="docutils literal">SIGPIPE</tt>信号而意外结束，在写操作频繁的情况下很容易触发：</p>
<pre class="literal-block">
inotifywait -m -o fifo .
</pre>
<p>只要inotifywait命令有输出，就会不停地修改fifo文件并产生更多输出，很快就会退出并返回<tt class="docutils literal">141</tt>，即<tt class="docutils literal">128 + 13 (SIGPIPE)</tt>。</p>
<p>（完）</p>

    </div>
<nav class="nav sidebar">
    <div class="siteinfo">
        <div class="sitename"><a href="../..">coinfaces</a></div>
        <div class="tagline">Another Side of Life</div>
    </div>

        <a href="../../categories/">categories</a>
        <a href="../..">&larr; Home</a>
</nav><footer class="footer">
    <span>
        &copy; jpli &middot;
        under <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">CC-BY-SA 4.0</a>
    </span>
    |
    <span>
        Powered by:
        <a href="http://blog.getpelican.com/">Pelican</a>
    </span>
</footer></body>
</html>